/**
  ETFAna project, Anyang Normal University && IMP-CAS
  \class ETFAnalyzer
  \brief a worker class defining the main analysis procedures
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2024-06-13
  \date 2024-06-19 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date         <th>Author      <th>Description                   </tr>
  <tr>  <td>2024-06-13   <td>Asia Sun    <td>file created                  </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#ifndef ETFAnalyzer_h
#define ETFAnalyzer_h

#include <initializer_list>
#include <vector>
#include <string>
#include "ETFTask.h"

using std::initializer_list;
using std::vector;
using std::string;

class ETFPID;
class ETFPIDm;
class ETFDetectorManager;
class ETFTrackManager;
class ETFPIDManager;
class ETFVisual;
class ETFAuxAna;

class ETFAnalyzer{
public:
  ETFAnalyzer();
  virtual ~ETFAnalyzer();

  virtual void Init();
  virtual void Analyze();
  virtual void PID(); // do the PID task
  virtual void PrintPerEvent();
  virtual void PrintPerEventOnline();
  virtual void PrintSummary();
  virtual void Register();
  virtual void AddDrawEvent(int ev){ fDrawVec.push_back(ev); }
  virtual void AddDrawEvent(const initializer_list<int> &l){ for(int i : l) AddDrawEvent(i); }
  virtual void AddDrawEvent(const vector<int> &v){ for(int i : v) AddDrawEvent(i); }

  /// analysis level: 0: no mapping; 1: 2D tracking; 2: PID; 3: 3D tracking
  virtual void SetAnaLevel(int l){ fAnaLevel = l; }
  int AnaLevel() const{ return fAnaLevel; }
  void SetIs3DTracking(bool opt){ fIs3DTracking = opt; }
  void SetDetDebug(bool opt = true){ fDetDebug = opt; }
  void SetTrackingDebug(bool opt = true){ fTrackingDebug = opt; }
  void SetPIDDebug(bool opt = true){ fPIDDebug = opt; }

  vector<ETFPXISection *> &GetPXISections(){ return fPXISections; }
  vector<ETFVMEEvent *> &GetVMEEvents(){ return fVMEEvents; }
  ETFPID *GetPID() const{ return fPID; }
  ETFPIDm *GetPIDm() const{ return fPIDm; }
  double phiAvrg() const{ return fPhiAvrg; } ///< phi averaged over postMag-DCs
  unsigned Index() const{ return fIndex; }
  unsigned CntEv() const{ return fCntEv; }

  // ClassDef(ETFAnalyzer, 0); // abstract base class for tasks in the Trackinging stage

protected:
  string fConfigDir; ///< containing configuration files
  vector<ETFPXISection *> fPXISections;
  vector<ETFVMEEvent *> fVMEEvents;
  vector<int> fDrawVec; ///< event index list to be drawn

  bool fDetDebug;
  bool fTrackingDebug;
  bool fPIDDebug;
  bool fIs3DTracking; ///< whether do the 3D tracking
  bool fIsPIDm; ///< whether to enable the light-frag PID (i.e., other than the heavy residue)
  int fAnaLevel; ///< 0: only mapping; 1: 2D tracking; 2: PID;
  double fPhiAvrg; ///< a broker between postMagTrker and ETFDC

  // the managers //
  ETFRun *fRun;
  ETFSource *fSrc;
  ETFParaManager *fpm;
  ETFDetectorManager *fdm;
  ETFAuxAna *fAuxAna; ///< auxiliary analysis
  ETFTrackManager *ftm;
  ETFPIDManager *fpidm;
  ETFPID *fPID; ///< for pid of the heavy residue, i.e., the core
  ETFPIDm *fPIDm; ///< for pid of light fragments, e.g., proton, pion, deutron, etc.
  ETFVisual *fVis;

  // accumulator //
  /// number of X trks, PIDed events and PIDed particles
  unsigned fIndex; ///< event index
  unsigned fCntEv; ///< number of analysed events
  unsigned fCntTrkX, fCntaoz, fCntPtl; // ptl: particle
  unsigned fCntTrk3D; ///< nof 3d tracks, including the around TA zone and post-mag ones
};

#endif
